using System;
using System.Text;
using CI.Organism;

namespace CI.Interfaces
{
    /// <summary>Hosting environment, this drives the looping of the processing of the organisms</summary>
    public interface IHostingEnvironment
    {
        /// <summary>Organisms</summary>
        IOrganismCollection Organisms { get; set; }

        /// <summary>Simulation, if set it has rules and checks that it runs</summary>
        ISimulationRestrictions Simulation { get; set; }

        /// <summary>Fitness function</summary>
        IFitnessFunction FitnessFunction { get; set; }

        /// <summary>Minimum time per heartbeat for all Organisms</summary>
        TimeSpan HBOrganismCollectionMin { get; set; }

        /// <summary>
        /// Environment scenario
        /// </summary>
        IScenario EnvironmentScenario { get; set; }

        /// <summary>
        /// Check and make sure the organism is within the bounds of the environment
        /// </summary>
        /// <param name="organism"></param>
        /// <returns>true if outside the bounds</returns>
        bool BoundsChecking(IOrganism organism);

        /// <summary>
        /// Processing state eg, working, pausing
        /// </summary>
        string ProcessingState { get; set; }

        /// <summary>Physical aspects of the hosting environment</summary>
        IHostingEnvironmentPhysical HostingEnvironmentPhysical { get; set; }

        /// <summary>System lag time of computing the entites, difference between acceptable time and actual</summary>
        TimeSpan LagTime { get; }

        /// <summary>System Heart Beat counter</summary>
        UInt32 SystemHeartBeat { get; }

        /// <summary>System start time used for calculating running time</summary>
        DateTime StartTime { get; }

        /// <summary>
        /// Version of Hosting Environment
        /// </summary>
        string VersionInformation { get; }

        /// <summary>Start the hosting environment</summary>
        void Start();

        /// <summary>Called to register the childOrganism in the environment, this may be different per environment</summary>
        void RegisterPhysicalCell(ICell _cell, ActionType _actionType);

    }
}
